#ifndef HILL_CIPHER_H
#define HILL_CIPHER_H

#include <string>
#include<string.h>
//#include <memory.h>
#include <cstdlib>
#include <ctime>
//#include <cstdio>
#include <cmath>
#include<sstream>
#include<vector>
using namespace std;
struct GCD
{
    int x;
    int y;
    int d;
};
class Hill_Cipher
{

public:
    Hill_Cipher(int num);

    ~Hill_Cipher();
    //产生随机矩阵
    void creatRMatrix(int num);
    //求矩阵的行列式
    int Det(vector<vector<int> > matrix, int row);
    //求两个数的最大公约数
    int gcd(int a, int b);
    /*判断矩阵K是否在模26的情况下可逆
     *矩阵在模26的情形下存在可逆矩阵的充分必要条件是gcd(det K,26) = 1 */
    bool ifInverse(vector<vector<int>> matrix);
    //矩阵相乘
    void multiphy(vector<vector<int>> matrix, vector<int>p, int row);
    //求出伴随矩阵
    void adjointMatrix(vector<vector<int>> matrix, int row);
    //将明文加密为密文
    std::string encryption( std::string plaintext);
    //将密文解密为明文(为了辨识清楚,我们统一以小写字母作为明文,大写字母作为密文)
    std::string deciphering();
    //欧几里得算法求模的逆
    GCD extendEuclid(int a, int b);
    //模逆运算
    int inverse(int a, int m);
    //由于C++不存在负数取模的内置函数,现在自己设定一个
    //定义一个模M的值
    int Mod(int a);
    //判断输入的明文是否全小写字母
    static bool includeOtherChar(std::string inStr);
    //判断输入的密文是否全大写字母
    static bool includeOtherChar1(std::string inStr);
    //string 输出秘钥
    std::string KtoString();
    //string秘钥转K
    void stringToK(std::string strKey);
    //string密文转C
    void stringToC(std::string strCiphertext);
    //定义5*5的加密矩阵
    vector<vector<int>>K;
    //定义5*5的解密矩阵   
    vector<vector<int>>D;
    //用于存放余子阵
    vector<vector<int>> cofa;

    vector<vector<int>> temp;
    int ROW, COL;
    /*
    int* P;  //明文单元
    int* C;  //密文单元
    int* F;  //密文解密后的单元
    */
    vector<int>P;
    vector<int>C;
    vector<int>F;

};
#endif // HILL_CIPHER_H
